package com.aizuda.boot.modules.common.util;

import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.xmlbeans.XmlToken;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageMar;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;

import java.io.File;
import java.io.FileOutputStream;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

/**
 * @author hjw
 * @description 浮动文本框工具类 目前只支持docx
 * @date 2025年01月12日
 */
public class DocxTextInserterUtil {
    /**
     * 插入浮动文本框到 Word 文档正文首段中（自动处理边距）
     *
     * @param inputPath  原始 Word 文件路径（.docx）
     * @param outputPath 输出 Word 文件路径（不能与输入路径相同）
     * @param text       要插入的文本内容
     * @param position   文本框的位置参数
     * @throws Exception
     */
    public static void insertFloatingTextbox(String inputPath, String outputPath, String text, TextBoxPosition position) throws Exception {
        if (inputPath.equals(outputPath)) {
            throw new IllegalArgumentException("输出文件路径不能与输入文件相同，避免覆盖源文件");
        }

        // 临时复制文件以便安全写入
        File tempFile = File.createTempFile("temp_doc_", ".docx");
        Files.copy(new File(inputPath).toPath(), tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);

        try (XWPFDocument document = new XWPFDocument(OPCPackage.open(tempFile))) {
            // 自动计算边距偏移
            int[] margins = getPageMargins(document);
            position.setMargin(margins[0], margins[1]);

            // 插入文本框
            XWPFParagraph firstPara = document.getParagraphArray(0);
            XWPFRun run = firstPara.createRun();
            run.getCTR().set(XmlToken.Factory.parse(generateVml(text, position)));

            try (FileOutputStream fos = new FileOutputStream(outputPath)) {
                document.write(fos);
            }

            System.out.printf("✅ 浮动文本框插入成功，边距 Left=%dpt, Top=%dpt%n", margins[0], margins[1]);
        } finally {
            tempFile.delete();
        }
    }

    /**
     * 获取页面左、上边距（单位 pt）
     */
    private static int[] getPageMargins(XWPFDocument document) {
        int leftPt = 0, topPt = 0;
        CTSectPr sectPr = document.getDocument().getBody().getSectPr();
        if (sectPr != null && sectPr.isSetPgMar()) {
            CTPageMar mar = sectPr.getPgMar();
            if (mar.getLeft() != null) {
                leftPt = -(int) Math.round(((BigInteger) mar.getLeft()).doubleValue() / 20.0);
            }
            if (mar.getTop() != null) {
                topPt = -(int) Math.round(((BigInteger) mar.getTop()).doubleValue() / 20.0);
            }
        }
        return new int[]{leftPt, topPt};
    }

    /**
     * 生成 VML 浮动文本框 XML 片段
     */
    private static String generateVml(String text, TextBoxPosition pos) {
        return String.format("""
                        <w:pict xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
                                xmlns:v="urn:schemas-microsoft-com:vml"
                                xmlns:o="urn:schemas-microsoft-com:office:office">
                          <v:shape id="FloatingTextBox" type="#_x0000_t202"
                            style="position:absolute;left:%dpt;top:%dpt;width:%dpt;height:%dpt;
                                   margin-left:%dpt;margin-top:%dpt;
                                   z-index:251658240;visibility:visible;
                                   mso-wrap-style:square;mso-width-relative:page;mso-height-relative:page;"
                            filled="false" stroked="false"
                            o:allowincell="false" o:layoutInCell="false" o:insetmode="auto">
                            <v:textbox inset="2pt,2pt,2pt,2pt">
                              <w:txbxContent>
                                <w:p>
                                  <w:r>
                                    <w:rPr>
                                      <w:rFonts w:ascii="宋体" w:hAnsi="宋体" w:cs="宋体"/>
                                      <w:sz w:val="22"/>
                                      <w:b/>
                                      <w:color w:val="000000"/>
                                    </w:rPr>
                                    <w:t>%s</w:t>
                                  </w:r>
                                </w:p>
                              </w:txbxContent>
                            </v:textbox>
                          </v:shape>
                        </w:pict>
                        """,
                pos.leftPt, pos.topPt,
                pos.widthPt, pos.heightPt,
                pos.marginLeftPt, pos.marginTopPt,
                text);
    }

    /**
     * 文本框参数类
     */
    public static class TextBoxPosition {
        public int leftPt;
        public int topPt;
        public int widthPt;
        public int heightPt;
        public int marginLeftPt;
        public int marginTopPt;

        public TextBoxPosition(int leftPt, int topPt, int widthPt, int heightPt) {
            this.leftPt = leftPt;
            this.topPt = topPt;
            this.widthPt = widthPt;
            this.heightPt = heightPt;
        }

        public void setMargin(int left, int top) {
            this.marginLeftPt = left;
            this.marginTopPt = top;
        }
    }

    public static void main(String[] args) throws Exception {
        String input = "/Users/apple/Downloads/test.docx";
        String output = "/Users/apple/Downloads/test_output.docx";
        String text = "PB-2025-001-" + System.currentTimeMillis();

        DocxTextInserterUtil.TextBoxPosition position =
                new DocxTextInserterUtil.TextBoxPosition(0, 0, 200, 30); // 左上角浮动文本框

        DocxTextInserterUtil.insertFloatingTextbox(input, output, text, position);
    }
}
